package com.ruoyi.project.file.service;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.CannedAccessControlList;
import com.aliyun.oss.model.CreateBucketRequest;
import com.aliyun.oss.model.PutObjectResult;
import com.ruoyi.common.utils.aliyunoss.FileMd5Util;
import com.ruoyi.common.utils.aliyunoss.ImageVEntity;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.project.file.domain.GlobalFileModel;
import com.ruoyi.project.file.mapper.GlobalFileMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

/**
 * @author Administrator
 */
@Service
@Slf4j
@Transactional
public class OssServiceImpl extends BaseService implements OssService {

    /**
     * 阿里云API的密钥Access Key ID
     */
    @Value("${oss.accessKeyId}")
    private String accessKeyId;
    /**
     * 阿里云API的密钥Access Key Secret
     */
    @Value("${oss.accessKeySecret}")
    private String accessKeySecret;
    /**
     * 阿里云API的bucket名称
     */
    @Value("${oss.bucketName}")
    private String bucketName;
    /**
     * 阿里云API的内或外网域名
     */
    @Value("${oss.endpoint}")
    private String endpoint;

    @Value("${oss.url}")
    private String url;

    private String[] imgPrefix = new String[]{"jpg", "png", "jpeg"};
    private String[] recording = new String[]{"mp3"};
    private String[] av = new String[]{"avi","mpg","mlv","mpe","mpeg","dat","mp4"};

    /**
     * 图片默认缩放比率
     */
    private static final double DEFAULT_SCALE = 0.5d;
    /**
     * 原图后缀
     */
    private static final String primary=".primary.png";

    @Autowired
    FileMd5Util fileMd5Util;

    @Resource
    GlobalFileMapper globalFileMapper;

    @Override
    public AjaxResult upload(MultipartFile file) throws IOException {
        if (file.isEmpty()) {
            return AjaxResult.error("文件为空");
        }
        Long size=file.getSize();
        if (size > fileSize) {
            logger.info("文件过大:"+size);
            return AjaxResult.error("文件过大");
        }
        String fileMd5=fileMd5Util.getFileMd5Value(file);
        GlobalFileModel globalFileModel=globalFileMapper.selectByPrimaryKey(fileMd5);
        if(null!=globalFileModel){
            log.info("重复文件：{}",globalFileModel);
            return AjaxResult.success("操作成功,文件已存在，直接读取：",globalFileModel.getFileUrl());
        }
        String url;
        ImageVEntity isImage=ossUtil.getType(file,fileMd5);
        if(isImage.isImage()){
            log.info("检测到是图片。。。。");
            //进行原图压缩
            log.info("进行压缩图片。。。。");
//            BufferedImage bufferedImage=Thumbnails.of(file.getInputStream()).size(375,375).asBufferedImage();
//            log.info("开始上传压缩版图片");
//            url = ossUtil.upload(bufferedImage,isImage);

            url=ossUtil.uploadObjectOSS(file,isImage);
            log.info("文件上传地址为：{}",url);
            log.info("开始上传原图");
            isImage.setUrl(isImage.getUrl()+primary);
            ossUtil.uploadObjectOSS(file,isImage);
        }else{
            log.info("检测到不是图片。。。。。。。。。。。。。");
            url=ossUtil.uploadObjectOSS(file,isImage);
        }

        globalFileModel=new GlobalFileModel();
        globalFileModel.setFileMd5(fileMd5);
        globalFileModel.setFileUrl(url);
        globalFileMapper.insertSelective(globalFileModel);
        return AjaxResult.success("操作成功",url);
    }

    @Override
    public AjaxResult upload(MultipartFile[] files) throws IOException {
//        ResultModel<List<String>> resultModel = ResultModel.success();
//        AjaxResult resultModel = AjaxResult.success();
        List<String> urlList = new LinkedList();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < files.length; i++) {
            AjaxResult result = upload(files[i]);
            result.success(result);
            if(result.get("code").toString().equals("200")){
                sb.append("第"+i+"张图"+result.get("msg").toString()+";");
                urlList.add(result.get("msg").toString());
            } else {
                sb.append("第"+i+"张图"+result.get("msg").toString()+";");
                AjaxResult.success(result.get("code").toString(),"第"+i+"张图"+result.get("msg").toString());
            }
        }
//        resultModel.setMessage(String.valueOf(sb));
        return AjaxResult.success(String.valueOf(sb),urlList);
    }



    public String getOssUrl() {
        return url;
    }

    /**
     * 判断容器是否存在,不存在就创建
     * @param client
     */
    public void  isBucket(OSSClient  client){
        // 判断容器是否存在,不存在就创建
        if (!client.doesBucketExist(bucketName)) {
            client.createBucket(bucketName);
            CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
            createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
            client.createBucket(createBucketRequest);
        }
    }

    /**
     * 更加日期创建文件夹
     *
     * @param prefix 后缀
     * @return
     */
    private String getType(String prefix) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String date = sdf.format(new Date());
        StringBuffer buffer = new StringBuffer("one-stand/");
        for (String i : imgPrefix) {
            if (i.toLowerCase().equals(prefix.toLowerCase())) {
                buffer.append("photo/").append(date).append("/").append(System.currentTimeMillis()).append(".").append(prefix);
                return buffer.toString();
            }
        }
        for (String r : recording) {
            if (r.toLowerCase().equals(prefix.toLowerCase())) {
                buffer.append("recording/").append(date).append("/").append(System.currentTimeMillis()).append(".").append(prefix);
                return buffer.toString();
            }
        }
        for (String r : av) {
            if (r.toLowerCase().equals(prefix.toLowerCase())) {
                buffer.append("video/").append(date).append("/").append(System.currentTimeMillis()).append(".").append(prefix);
                return buffer.toString();
            }
        }
        return buffer.append("other/").append(date).append("/").append(System.currentTimeMillis()).append(".").append(prefix).toString();
    }

    /**
     * 上传文件至OSS
     * @param  file File
     * @param  inputStream 文件流
     * @return String 返回的唯一MD5数字签名
     */
    public String uploadObjectOSS(File file, InputStream inputStream) {
        OSSClient client=new OSSClient(endpoint, accessKeyId, accessKeySecret);
        isBucket(client);
        try {
            client.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
            String fileName = file.getName();
            String prefix = fileName.substring(fileName.lastIndexOf(".") + 1);
            String fileUrl = getType(prefix);
            PutObjectResult result = client.putObject(bucketName, fileUrl, inputStream);
            if (result != null) {
                return fileUrl;
            }
        } catch (Exception e) {
            log.error("上传文件至OSS[异常]",e);
        } finally {
            client.shutdown();
            try {
                inputStream.close();
            } catch (IOException e) {
                log.error("关闭客户端[异常]",e);
            }
        }
        return null;
    }

}
